package org.andes.kownledge;

import java.util.HashMap;
import java.util.Map;

import org.armedbear.lisp.LispObject;
import org.armedbear.lisp.Load;
import org.armedbear.lisp.Pathname;

public class ProblemManager {
	

	public static HashMap<String,Problem> ProblemRegistry=new HashMap<String,Problem>();
    private static LispObject[] key_values;
	private static int probindex=2;
	
	public static void readProblem() throws Exception{
		Pathname pathname = new Pathname("kinematics-problems.cl");
		LispObject lo=Load.loadOnly(pathname, false, false, true);
		key_values=lo.copyToArray();
		Problem prob=new Problem();
		prob.setName(key_values[1].getStringValue());
		while(probindex<key_values.length){
			processProblemDefElem(prob);
		}
		ProblemRegistry.put(prob.getName(), prob);	
	}
	private static void processProblemDefElem(Problem prob){
		
		String key=key_values[probindex++].getStringValue();
		LispObject value=key_values[probindex++];	
		if(key.equalsIgnoreCase("soughts")){	
			prob.setSoughts(value.copyToArray());
		}else if(key.equalsIgnoreCase("givens")){	
			prob.setGivens(value.toList());
		}		
	}
    
    public void defProblem(){
    	
    }
    
    
   
    
    
    //------------------------------------------------------------------
    // problem access.


//    (defun get-problem (P)
//      "Get the named problem from the *Problem-Registry* Hashtable."
//      (gethash P *Problem-Registry*))
    public static Problem getProblem(String name){
    	return ProblemRegistry.get(name);
    }

//    (defun add-problem (Prob)
//      "Add a problem to the *Problem-Registry* Hashtable."
//        (setf (gethash (Problem-name Prob) *Problem-Registry*) Prob))
    public void addProblem(){
    	
    }
        
        
        
    ////////////////////////////////////////////////////////////////////;
    // map-problems
    // Map the specified function onto each registered problem in turn.
    // this is used primarily for dump-problems.
    //
    // non-null filter-fn is a predicate of a problem used to filter set 
    // of problems applied to.  Default is null filter for all problems.
    // working-problem-p is filter for problems tagged 'working only
//    (defun map-problems (Function &optional (filter-fn NIL))
//      "Map the specified function onto each problem struct in turn."
//      (maphash #'(lambda (Name Problem)
//    	       (declare (ignore Name))
//    	       (when (or (null filter-fn)
//    			 (funcall filter-fn Problem))
//    		 (funcall Function Problem)))
//    	   *Problem-Registry*))
    public void mapProblem(){
    	
    }

//    (defun listprobs () 
//      "list of problems in alphabetical problem name order"
//      (let ((values))
//        (maphash #'(lambda (key value) (declare (ignore key))
//    		       (push value values)) *Problem-Registry*)
//        (sort values #'string< :key #'problem-name)))
//
//    (defun working-problem-p (problem)
//      "Test if problem is tagged as working"
//       (member 'working (problem-features problem)))
//
//    (defun no-quant-problem-p (problem)
//      "Return t iff the problem is a no-quant problem."
//      (notany #'quantity-expression-p (problem-soughts problem)))
//
//
//    (defun multi-sought-problem-p (Problem)
//      "Does the problem seek more than 1 sought?"
//      (< 1 (length (problem-soughts Problem))))
//
//
//    (defun single-sought-problem-p (Problem)
//      "Does the problem have only 1 sought?"
//      (= 1 (length (problem-soughts Problem))))
//
//    (defun problem-has-feature-p (Problem Feature)
//      "Return t if the specified problem has the specified feature."
//      (member Feature (problem-features Problem)))
    

}
